package com.example.base.plugin;

import com.example.base.app.AppFunctionMap;
import com.example.base.system.SysAppService;
import com.example.base.system.domain.SysApp;
import com.example.base.util.AppClassLoader;
import com.example.base.util.URLClassLoaderUtils;
import com.example.base.utils.ReflectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.net.URLClassLoader;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class LoadPluginService {

    @Autowired
    private SysAppService sysAppService;

    @Autowired
    private AppFunctionMap appFunctionMap;

    @Autowired
    private ThreadPoolTaskExecutor asyncServiceExecutor;




    public void loadPlugin(String appName){
        asyncServiceExecutor.execute(()->{
            log.info("开始加载应用 appPlugin: {} job",appName);
            SysApp sysApp=sysAppService.getSysAppByAppName(appName);
            URLClassLoader urlClassLoader= URLClassLoaderUtils.getClassLoaderMap().get(sysApp.getAppFilename());
            if(urlClassLoader!=null){
                if(urlClassLoader instanceof AppClassLoader){
                    AppClassLoader appClassLoader=(AppClassLoader) urlClassLoader;
                    Map<String, Class<?>> classMap= appClassLoader.getLoadedClasses();
                    for (Map.Entry<String,Class<?>> map:classMap.entrySet()){
                        if(ReflectUtils.isClassImplementedInterface(map.getValue(),AppPlugin.class)){
                            log.info("AppPlugin class:{}",map.getValue().getName());
                            AppPlugin appPlugin= (AppPlugin) ReflectUtils.getObjectByClass(map.getValue());
                            List<Plugin> appPluginList=appPlugin.loadPlugin();
                            appPluginList.forEach((e)->{
                                if(e.getAppFunction()!=null){
                                    appFunctionMap.addFunction(appName,e.getAppFunction().getAppFunctionName(),e.getAppFunction());
                                }
                            });
                        }
                    }
                }
            }
        });
    }
}
